﻿using Core.IRepository;
using Core.IServices;
using Services.Aspects;
using System;
using System.Linq;
using System.Collections;
using System.Collections.Generic;
using Core.Dtos;
using Shared.Mappers;
using Core.Domain;
using Core.Messages;
using Core.Queries;

namespace Services
{
    [CacheName("Person")]
    public class PersonService : IPersonService
    {
        private readonly IPersonRepository personRepository;        
        private readonly IUnitOfWork unitOfWork;
        private readonly IObjMapper mapper;

        public PersonService(IUnitOfWork unitOfWork, IPersonRepository personRepository, IObjMapper mapper)
        {            
            this.personRepository = personRepository;            
            this.unitOfWork = unitOfWork;
            this.mapper = mapper;
        }

        [HandleServiceError]
        [Cache]
        public Response<PersonDto> FindById(int id)
        {            
            Response<PersonDto> response = new Response<PersonDto>();
            var entity = personRepository.FindBy(id);
            response.Value = mapper.Map<PersonDto>(entity);
            response.Success = true;
            return response;
        }

        [HandleServiceError]
        public QueryResponse<PersonDto> FindBy(PersonQuery query)
        {
            QueryResponse<PersonDto> response = new QueryResponse<PersonDto>();
            var list = personRepository.FindBy(query);
            response.List = mapper.MapList<Person, PersonDto>(list);
            if (query.Count)
                response.TotalCount = personRepository.Count(query);
            response.PageNumber = query.PageNumber;
            response.PageSize = query.PageSize;
            response.Success = true;
            return response;
        }

        [HandleServiceError]
        public Response<int> Add(PersonDto dto)
        {
            Response<int> response = new Response<int>();

            Person entity = mapper.Map<Person>(dto);            

            if (entity.Validate())
            {
                personRepository.Add(entity);
                unitOfWork.Commit();
                response.Value = entity.Id;
                response.Success = true;
            }
            else
            {
                response.Success = false;
                response.BrokenRules = entity.BrokenRules;
            }

            return response;
        }

        [HandleServiceError]
        [DeleteCache]
        public Response Edit(int id, PersonDto dto)
        {
            Response response = new Response();
        
            Person entity = personRepository.FindBy(id);
            mapper.Map<PersonDto, Person>(dto, entity);

            if (entity.Validate())
            {
                personRepository.Edit(entity);
                unitOfWork.Commit();
                response.Success = true;
            }
            else
            {
                response.Success = false;
                response.BrokenRules = entity.BrokenRules;
            }

            return response;
        }

        [HandleServiceError]
        [DeleteCache]
        public Response Delete(int id)
        {
            Response response = new Response();
            Person entity = personRepository.FindBy(id);

            if (entity != null)
            {
                personRepository.Delete(entity);
                unitOfWork.Commit();
            }
            response.Success = true;

            return response;
        }        
    }
}
